"""
角色表 Schema
"""

from datetime import datetime
from typing import Literal, Optional

from pydantic import Field, field_serializer, field_validator

from app.schemas.base import BaseSchema


class RoleBase(BaseSchema):
    """角色表 基础模型"""

    name: str = Field(max_length=64, description="角色名称", alias="name")
    code: str = Field(max_length=32, description="角色编码", alias="code")
    sort: Optional[int] = Field(default=None, description="显示顺序", alias="sort")
    status: Optional[Literal[0, 1]] = Field(default=None, description="角色状态(1-正常 0-停用)", alias="status")
    data_scope: Optional[Literal[1, 2, 3, 4]] = Field(
        default=None, description="数据权限(1-所有数据 2-部门及子部门数据 3-本部门数据 4-本人数据)", alias="dataScope"
    )


class RoleCreate(RoleBase):
    """创建角色表 模型"""

    pass


class RoleUpdate(RoleBase):
    """更新角色表 模型"""

    name: Optional[str] = Field(default=None, max_length=64, description="角色名称", alias="name")
    code: Optional[str] = Field(default=None, max_length=32, description="角色编码", alias="code")
    sort: Optional[int] = Field(default=None, description="显示顺序", alias="sort")
    status: Optional[Literal[0, 1]] = Field(default=None, description="角色状态(1-正常 0-停用)", alias="status")
    data_scope: Optional[Literal[1, 2, 3, 4]] = Field(
        default=None, description="数据权限(1-所有数据 2-部门及子部门数据 3-本部门数据 4-本人数据)", alias="dataScope"
    )


class RolePublic(RoleBase):
    """角色表 公共模型，用于API响应"""

    id: int = Field(alias="id", description="主键")
    name: str = Field(alias="name", max_length=64, description="角色名称")
    code: str = Field(alias="code", max_length=32, description="角色编码")
    sort: Optional[int] = Field(default=None, alias="sort", description="显示顺序")
    status: Optional[int] = Field(default=None, alias="status", description="角色状态(1-正常 0-停用)")
    data_scope: Optional[int] = Field(
        default=None, alias="dataScope", description="数据权限(1-所有数据 2-部门及子部门数据 3-本部门数据 4-本人数据)"
    )
    create_by: Optional[int] = Field(default=None, alias="createBy", description="创建人 ID")
    create_time: Optional[datetime] = Field(default=None, alias="createTime", description="创建时间")
    update_by: Optional[int] = Field(default=None, alias="updateBy", description="更新人ID")
    update_time: Optional[datetime] = Field(default=None, alias="updateTime", description="更新时间")


class RolePageVO(BaseSchema):
    """角色分页对象"""

    id: int = Field(alias="id", description="角色ID")
    name: str = Field(alias="name", description="角色名称")
    code: str = Field(alias="code", description="角色编码")
    status: int = Field(alias="status", description="角色状态")
    sort: int = Field(alias="sort", description="排序")
    create_time: datetime = Field(alias="createTime", description="创建时间")
    update_time: Optional[datetime] = Field(None, alias="updateTime", description="更新时间")

    @field_serializer("create_time", "update_time", when_used="json")
    def serialize_datetime(self, v: datetime, _info):
        if v is None:
            return None
        return v.strftime("%Y-%m-%d %H:%M:%S")


class RolePageQuery(BaseSchema):
    """角色分页查询对象"""

    keywords: Optional[str] = Field(default=None, description="关键字(角色名称/角色编码)", alias="keywords")
    start_date: Optional[datetime] = Field(default=None, description="开始日期", alias="startDate")
    end_date: Optional[datetime] = Field(default=None, description="结束日期", alias="endDate")
    is_root: Optional[bool] = Field(default=None, alias="isRoot", description="是否超级管理员")
    page_num: int = Field(default=1, min=1, alias="pageNum", description="页码")
    page_size: int = Field(default=10, min=10, max=1000, alias="pageSize", description="每页记录数")


class RoleForm(BaseSchema):
    """角色表单对象"""

    id: Optional[int] = Field(default=None, description="角色ID", alias="id")
    name: str = Field(description="角色名称", alias="name")
    code: str = Field(description="角色编码", alias="code")
    sort: Optional[int] = Field(default=None, description="排序", alias="sort")
    status: Optional[int] = Field(default=None, description="角色状态(1-正常；0-停用)", alias="status")
    data_scope: Optional[int] = Field(default=None, description="数据权限", alias="dataScope")

    @field_validator("status", mode="after")
    @classmethod
    def validate_status(cls, v: int) -> int:
        """校验角色状态"""
        if v is None:
            return None
        if v not in [0, 1]:
            raise ValueError("角色状态不正确")
        return v
